Skip to content

ref(onboarding): Introduce content blocks #95224

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

ArthurKnaus
Copy link
Member

@ArthurKnaus ArthurKnaus commented Jul 10, 2025

Introduce specialized content blocks opposed to the current configuration object.
This makes it clearer what is rendered in which order and which properties are required -> enforced by types.
Converted react and java project creation onboarding docs. (also removed not-needed profiling content from react docs)

@github-actions github-actions bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Jul 10, 2025
Comment on lines +43 to +46
const partialLoading = useMemo(
() => children.includes(PACKAGE_LOADING_PLACEHOLDER),
[children]
);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously we had a separate prop partiallyLoading on the configuration object, which was missing most of the time. I decided to drop it from the new format and rather autodetect the loading placeholder in the snippet. This solution is maybe a bit hacky but is much better DX when writing docs.

*
* **Do not** use this with custom react elements but instead use the `custom` block type.
*/
text: React.ReactNode;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would love to only have string here. Also the translation functions are making the docs so much harder to read...

Copy link

codecov bot commented Jul 10, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #95224   +/-   ##
=======================================
  Coverage   87.84%   87.85%           
=======================================
  Files       10469    10469           
  Lines      605374   605361   -13     
  Branches    23674    23672    -2     
=======================================
- Hits       531819   531814    -5     
+ Misses      73195    73187    -8     
  Partials      360      360           

Comment on lines 56 to 61
export type ContentBlock =
| TextBlock
| CodeBlock
| CustomBlock
| AlertBlock
| ConditionalBlock;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just added the most basic ones that I encountered while converting java & react docs.
In the future we will for sure add more like heading, list, ...

Comment on lines +55 to +59
type: 'custom',
content: (
<OnboardingCodeSnippet
language="bash"
onCopy={() =>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onCopy and onSelectAndCopy was only supported for this one usage. Decided to resort to a custom block instead of bloating the interface.

@ArthurKnaus ArthurKnaus marked this pull request as ready for review July 11, 2025 07:27
@ArthurKnaus ArthurKnaus requested review from a team as code owners July 11, 2025 07:27
cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

Comment on lines -25 to -28
import {
getProfilingDocumentHeaderConfigurationStep,
MaybeBrowserProfilingBetaWarning,
} from 'sentry/components/onboarding/gettingStartedDoc/utils/profilingOnboarding';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch removing profiling 🎉

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah there is even more to do here! will create a ticket for it

`;

function TextBlock(block: Extract<ContentBlock, {type: 'text'}>) {
return <TextBlockWrapper>{block.text}</TextBlockWrapper>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return <TextBlockWrapper>{block.text}</TextBlockWrapper>;
return <div css={css`${baseBlockStyles} code:not([class*='language-']) {
color: ${p => p.theme.pink400};
}`}>{block.text}</div>;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 though I will move the style definition out of the render function so they are not serialized on every render

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah no, it needs the theme so I cant transform it to css

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can use useTheme

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tbh i find <TextBlockWrapper>{block.text}</TextBlockWrapper> way nicer and easier to work with then

<div css={css`${baseBlockStyles}  code:not([class*='language-']) {
    color: ${p => p.theme.pink400};
  }`}>{block.text}</div>;

Copy link
Member

@priscilawebdev priscilawebdev Jul 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have have a strong opinion here, but I am always in favour of having less code

Copy link
Member Author

@ArthurKnaus ArthurKnaus Jul 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, I checked the implementation of styled. It always serializes styles during render.
So from a performance view, static styles should be faster with the css annotation outside the component. But as soon as you use the theme or props inside the css it does not make a difference (at least with regards to style serialization).
Edit: My bad did not see that styled already implements a cache based on the template result. Same goes for the css prop handling. So no difference.

export const defaultBlocks: BlockRenderer = {
text: TextBlock,
code: CodeBlock,
custom: CustomBlock,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a bit confused about having a customBlock inside of defaultBlocks. is it a default custom block?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If i get this correctly it is a block component that is used by default when the type of the block is custom.

Copy link
Member Author

@ArthurKnaus ArthurKnaus Jul 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it is the default renderer for the block with type custom and just adds a wrapper div with margin so devs writing some custom jsx in the docs do not have to care about the spacing between content.

the block type custom is meant as the escape hatch if no other blocks fit:

/**
 * Custom blocks can be used to render any content that is not covered by the other block types.
 */
type CustomBlock = BaseBlock<'custom'> & {
  content: React.ReactNode;
};

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I get that, just the name is confusing

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe it helps renaming defaultBlocks to defaultRenderers 🤔

Copy link
Member

@priscilawebdev priscilawebdev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR has quite a few changes, which made it difficult to review...though I understand it was probably needed for the proof of concept. I’ve gone through all the code, and it looks really good. I especially like the comments you added to the new props and how you marked the old ones as deprecated. I also compared the rendered components to what we have in production, and everything seems just right. Nice work! 🚀

It might take me and maybe others a little time to get used to the new content blocks, but I think they’ll make our code cleaner and easier to work with.

Copy link
Member

@obostjancic obostjancic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as spam.

Comment on lines +19 to +23
const baseBlockStyles = css`
:not(:last-child) {
margin-bottom: var(${CssVariables.BLOCK_SPACING});
}
`;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use a <Alert.Container> here? It should add the margin for you

ContentBlock,
} from 'sentry/components/onboarding/gettingStartedDoc/contentBlocks/types';

export enum CssVariables {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use a styled component here?

I would suggest finding a more specific naming here given that these are exported, you wouldn't want them to pollute LSP suggestions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Scope: Frontend Automatically applied to PRs that change frontend components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants